package com.gss.service.stock;

import java.text.ParseException;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.gss.domain.common.SearchCriteria;
import com.gss.domain.stock.ItemDetailsDTO;
import com.gss.domain.stock.ItemTransactionDTO;
import com.gss.domain.stock.ItemTransactionDTO.OperationType;
import com.gss.persistance.stock.ItemDAO;
import com.gss.util.common.ApplicationConstant;
import com.gss.util.common.ApplicationUtilities;

@Service
public class ItemService 
{
	Logger logger = Logger.getLogger(ItemService.class);
	@Autowired
	ItemDAO itemDAO;
	
	public boolean saveItem(ItemDetailsDTO detailsDTO)
	{
		boolean isSuccess = false;
		logger.debug(detailsDTO.getItemName());
		ItemTransactionDTO itemTransactionDTO = new ItemTransactionDTO();
		
		itemTransactionDTO.setOpertionType(OperationType.Purchase);
		itemTransactionDTO.setQuantity(detailsDTO.getItemStock());
		itemTransactionDTO.setItemName(detailsDTO.getItemName());
		ApplicationUtilities.populateCommonDetails(itemTransactionDTO, true);
		
		ApplicationUtilities.populateCommonDetails(detailsDTO, true);
		if(itemDAO.saveItem(detailsDTO))
		{
			ApplicationConstant.ITEM_NAME_ID_MAP.put(detailsDTO.getItemName(), detailsDTO.getItemId());
			ApplicationConstant.ITEM_ID_ITEM_MAP.put(detailsDTO.getItemName(), detailsDTO);
			ApplicationConstant.ITEM_STOCK_MAP.put(detailsDTO.getItemName(), detailsDTO.getItemStock());
			itemTransactionDTO.setItem(detailsDTO);
			logger.debug(itemTransactionDTO.getItem().getItemId());
			itemDAO.saveTransaction(itemTransactionDTO);
			
			isSuccess=true;
		}
		return isSuccess;
	}
	public ItemDetailsDTO loadItemByName(String itemName)
	{
		ItemDetailsDTO detailsDTO = new ItemDetailsDTO();
		detailsDTO.setItemName(itemName);
		itemDAO.loadItemByName(detailsDTO);
		return detailsDTO;
	}
	public boolean updateItemDetails(ItemDetailsDTO itemDetails,String oldItemName) {
		boolean isSuccess = false;
		if(itemDAO.updateItemDetails(itemDetails)){
			isSuccess = true;
			ApplicationUtilities.populateCommonDetails(itemDetails, false);
			ApplicationConstant.ITEM_ID_ITEM_MAP.put(itemDetails.getItemName(), itemDetails);
			ApplicationConstant.ITEM_NAME_ID_MAP.put(itemDetails.getItemName(), itemDetails.getItemId());
			ApplicationConstant.ITEM_STOCK_MAP.put(itemDetails.getItemName(), itemDetails.getItemStock());
			ApplicationConstant.ITEM_ID_ITEM_MAP.remove(oldItemName);
			ApplicationConstant.ITEM_NAME_ID_MAP.remove(oldItemName);
			ApplicationConstant.ITEM_STOCK_MAP.remove(oldItemName);
		}
		return isSuccess;
		
	}
	public List<ItemDetailsDTO> loadAllItem() {
		
		return itemDAO.loadAllItem();
	}
	public boolean saveTransaction(ItemTransactionDTO itemTransactionDTO) {
		boolean isSuccess = false;
		ApplicationUtilities.populateCommonDetails(itemTransactionDTO, true);
		ItemDetailsDTO detailsDTO = new ItemDetailsDTO();
		itemTransactionDTO.setItem(ApplicationConstant.ITEM_ID_ITEM_MAP.get(itemTransactionDTO.getItemName()));
		detailsDTO.setItemId(ApplicationConstant.ITEM_NAME_ID_MAP.get(itemTransactionDTO.getItemName()));
		loadItemById(detailsDTO);
		if(itemTransactionDTO.getOpertionType().equals(OperationType.Purchase)|| itemTransactionDTO.getOpertionType().equals(OperationType.Return))
		{
			logger.debug("Return");
			detailsDTO.setItemStock(detailsDTO.getItemStock()+ itemTransactionDTO.getQuantity());
		}
		else
		{
			logger.debug(itemTransactionDTO.getOpertionType());
			detailsDTO.setItemStock(detailsDTO.getItemStock()- itemTransactionDTO.getQuantity());
		}
		
		if(itemDAO.saveTransaction(itemTransactionDTO))
		{
			isSuccess= true;
			ApplicationConstant.ITEM_STOCK_MAP.put(itemTransactionDTO.getItemName(), detailsDTO.getItemStock());
			ApplicationConstant.ITEM_ID_ITEM_MAP.put(itemTransactionDTO.getItem().getItemName(), detailsDTO);
			ApplicationConstant.ITEM_NAME_ID_MAP.put(itemTransactionDTO.getItem().getItemName(), detailsDTO.getItemId());
			ApplicationUtilities.populateCommonDetails(detailsDTO, false);
			itemDAO.updateItemDetails(detailsDTO);
		}
		return isSuccess;
	}
	private void loadItemById(ItemDetailsDTO detailsDTO) {
		
		itemDAO.loadItemById(detailsDTO);
		//return null;
	}
	public List<ItemDetailsDTO> getItemLessinStock() {
		DetachedCriteria criteria = DetachedCriteria.forClass(ItemDetailsDTO.class);
				criteria.add(Restrictions.leProperty("itemStock", "minItemStock"));
	
		return itemDAO.loadItemForLessStock(criteria);
	}
	public List<ItemTransactionDTO> getItemTransaction(SearchCriteria searchCriteria) throws ParseException {
		DetachedCriteria criteria = DetachedCriteria.forClass(ItemTransactionDTO.class);
		criteria.createAlias("item", "item");
		if(searchCriteria.getFromDate().getTime() == searchCriteria.getToDate().getTime())
			searchCriteria.setToDate(new Date(searchCriteria.getToDate().getTime() + 86400000));
		criteria.add(Restrictions.between("createdDate", searchCriteria.getFromDate(), searchCriteria.getToDate()));
		if(null != searchCriteria.getItemName() && !"".equals(searchCriteria.getItemName()))
			criteria.add(Restrictions.like("item.itemName",searchCriteria.getItemName(),MatchMode.ANYWHERE).ignoreCase());

		logger.debug(criteria);
		return itemDAO.getItemTransaction(criteria);
	}
}
